package com.ethink.warehouse.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.warehouse.api.constant.WarehouseRespCode;
import com.ethink.warehouse.api.enums.SubWarehouseSubWarehouseStatusEnum;
import com.ethink.warehouse.api.info.SubWarehouseInfo;
import com.ethink.warehouse.api.info.WarehouseInfo;
import com.ethink.warehouse.api.request.SubWarehouseAddRequest;
import com.ethink.warehouse.api.request.SubWarehouseQueryRequest;
import com.ethink.warehouse.api.request.SubWarehouseStatusSetRequest;
import com.ethink.warehouse.api.request.SubWarehouseUpdateRequest;
import com.ethink.warehouse.api.response.SubWarehouseAddResponse;
import com.ethink.warehouse.common.entity.SubWarehouse;
import com.ethink.warehouse.common.mapper.SubWarehouseMapper;
import com.ethink.warehouse.common.mapper.WarehouseMapper;
import com.ethink.warehouse.converter.SubWarehouseConverter;
import com.ethink.warehouse.service.SubWarehouseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 仓库分仓 Service接口实现
 *
 * @author default
 * @date 2022-11-01
 */
@Slf4j
@Service
public class SubWarehouseServiceImpl implements SubWarehouseService {

    @Autowired
    private SubWarehouseMapper subWarehouseMapper;

    @Autowired
    private WarehouseMapper warehouseMapper;

    @Autowired
    private SubWarehouseConverter subWarehouseConverter;

    @Override
    public Page<SubWarehouseInfo> querySubWarehouse(SubWarehouseQueryRequest request) {
        return subWarehouseMapper.querySubWarehouse(PageUtils.buildPage(request), request);
    }

    @Override
    public SubWarehouseInfo getSubWarehouseById(Long subWarehouseId) {
        return subWarehouseMapper.getSubWarehouseById(subWarehouseId);
    }

    @Override
    public List<SubWarehouseInfo> listSubWarehouse() {
        return subWarehouseMapper.listSubWarehouse();
    }

    @Override
    public Map<String, SubWarehouseInfo> listSubWarehouseMap() {
        return listSubWarehouse().stream().collect(Collectors.toMap(SubWarehouseInfo::getSubWarehouseCode, info -> info));
    }

    @Override
    public SubWarehouseAddResponse addSubWarehouse(SubWarehouseAddRequest request) {
        WarehouseInfo warehouseInfo = warehouseMapper.getWarehouseById(request.getWarehouseId());
        if (warehouseInfo == null) {
            throw new BusinessException(WarehouseRespCode.SUB_WAREHOUSE_ADD_WAREHOUSE_ID_NON_EXISTENT_ERR);
        }

        SubWarehouseAddResponse response = new SubWarehouseAddResponse();
        SubWarehouse subWarehouse = new SubWarehouse();
        BeanUtils.copyProperties(request, subWarehouse);
        subWarehouse.setSubWarehouseCode(this.generateSubWarehouseCode(warehouseInfo));
        subWarehouse.setSubWarehouseStatus(SubWarehouseSubWarehouseStatusEnum.OPEN.getIntValue());
        subWarehouseMapper.insert(subWarehouse);
        response.setId(subWarehouse.getId());
        return response;
    }

    @Override
    public void updateSubWarehouse(SubWarehouseUpdateRequest request) {
        LambdaUpdateWrapper<SubWarehouse> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SubWarehouse::getId, request.getId());
        updateWrapper.set(SubWarehouse::getSubWarehouseName, request.getSubWarehouseName());
        updateWrapper.set(SubWarehouse::getWarehouseBookId, request.getWarehouseBookId());
        updateWrapper.set(SubWarehouse::getSubWarehouseType, request.getSubWarehouseType());
        updateWrapper.set(SubWarehouse::getOwner, request.getOwner());
        updateWrapper.set(SubWarehouse::getOwnerName, request.getOwnerName());
        subWarehouseMapper.update(null, updateWrapper);
    }

    @Override
    public void setSubWarehouseStatus(SubWarehouseStatusSetRequest request) {
        LambdaUpdateWrapper<SubWarehouse> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SubWarehouse::getId, request.getId());
        updateWrapper.set(SubWarehouse::getSubWarehouseStatus, request.getSubWarehouseStatus());
        subWarehouseMapper.update(null, updateWrapper);
    }

    @Override
    public SubWarehouseInfo getSubWarehouseByCode(String subWarehouseCode) {
        return subWarehouseMapper.getSubWarehouseByCode(subWarehouseCode);
    }

    /**
     * 生成分仓编码
     *
     * @param warehouseInfo
     * @return
     */
    private String generateSubWarehouseCode(WarehouseInfo warehouseInfo) {
        LambdaQueryWrapper<SubWarehouse> subWarehouseQueryWrapper = new LambdaQueryWrapper<>();
        subWarehouseQueryWrapper.eq(SubWarehouse::getWarehouseId, warehouseInfo.getId());
        subWarehouseQueryWrapper.eq(SubWarehouse::getIsDeleted, false);
        subWarehouseQueryWrapper.likeRight(SubWarehouse::getSubWarehouseCode, warehouseInfo.getWarehouseCode());
        subWarehouseQueryWrapper.orderByDesc(SubWarehouse::getSubWarehouseCode);
        subWarehouseQueryWrapper.last(" limit 1");
        SubWarehouse subWarehouse = subWarehouseMapper.selectOne(subWarehouseQueryWrapper);
        StringBuilder codeBuilder = new StringBuilder();
        codeBuilder.append(warehouseInfo.getWarehouseCode());
        int sequence;
        if (subWarehouse == null) {
            sequence = 1;
        } else {
            int currentSequence;
            try {
                currentSequence = Integer.parseInt(subWarehouse.getSubWarehouseCode().replace(warehouseInfo.getWarehouseCode(), ""));
            } catch (Exception e) {
                log.error("", e);
                currentSequence = 0;
            }
            sequence = currentSequence + 1;
        }
        codeBuilder.append(String.format("%04d", sequence));
        return codeBuilder.toString();
    }

}